<?php
declare(strict_types=1);
/**
 * 申通API中心
 */
namespace Service\VenderClient\WayBillExpressCompanyApi;
use Service\Code\Normal;
use Service\BaseService;
use Service\ExtraService\TaskWorker;
use Service\HttpServer\Http;
class StoCompanyApiClient extends BaseService
{
    protected $config;
    const API_URL = 'http://cloudinter-linkgateway.sto.cn/gateway/link.do';
    public function __construct( array $apiBody = [] )
    {
        $this->config = $apiBody;
    }
    
    /**
     * 获取组装请求物流公司报文
     * @param array $logisticsGeneralInfo
     */
    public function logisticDeclare( array $declareInfo = [])
    {
        $receiveInfo = $declareInfo['receiveInfo'];
        $senderInfo  = $declareInfo['senderInfo'];
        $orderGoods  = $declareInfo['orderGoods'];
        $order       = $declareInfo['order'];
        
        //组装申报信息
        $logisticsGeneralInfo = [
            'ItemName'   => array_column($orderGoods, 'goods_name'),
            'PostFee'    => $order['price_express'], //运费
            'InsuredFee' => '0', //保价
            'TradeId'    => $order['sn'], //订单号（客户系统自己生成，唯一）,
        ];
        
        $goodsName = $logisticsGeneralInfo['ItemName'];
        if(is_array($logisticsGeneralInfo['ItemName'])){
            $goodsName = implode('|', $logisticsGeneralInfo['ItemName']);
        }
        $goodsName='保税商品';
        $senderInfo = [
            'name'     => $senderInfo['SenderName'],//发件人
            'mobile'   => $senderInfo['SenderPhone'],//发件人电话
            'province' => $senderInfo['SenderProvince'],//发件省
            'city'     => $senderInfo['SenderCity'],//发件市
            'area'     => $senderInfo['SenderCountry'],//发件区
            'address'  => $senderInfo['SenderAddress'],//发件人详细地址
        ];
    
        $receiver = [
            'name'     => $receiveInfo['ReceiverName'],//收件人
            'mobile'   => $receiveInfo['ReceiverPhone'],//收件人电话
            'province' => $receiveInfo['ReceiverProvince'],//收件省
            'city'     => $receiveInfo['ReceiverCity'],//收件市
            'area'     => $receiveInfo['ReceiverCountry'],//收件区
            'address'  => $receiveInfo['ReceiverAddress'],//收件人详细地址
        ];
    
        $cargo = [
            'battery'   => "10",
            'goodsType' => "小件",
            'goodsName' => $goodsName,
        ];
        $customer = [
            'siteCode'     => $this->config['WaybillPartnerKey'],//申通需要  网点编码必传
            'customerName' => $this->config['WaybillAuthUserName'],//申通需要  客户编码（不传单号时必传）
            'sitePwd'      => $this->config['WaybillAuthPassWord'],//申通需要  电子面单密码
        ];
        $internationalAnnex = [
            'internationalProductType' => "02",
            'customsDeclaration'       => true,
            'senderCountry'            => "CN",
            'receiverCountry'          => "CN",
        ];
    
        $extendFieldMap = [
            'otherInfo' => [
                'freight'    => $logisticsGeneralInfo['PostFee'],//运费，商品运输费用，无则填“0”
                'appType'    => $logisticsGeneralInfo['SyncbillOperationType'] ?? '1',//操作类型（根据业务选择区分赋值（1、4）
                'appStatus'  => "2",
                'billNo'     => "",
                'insuredFee' => $logisticsGeneralInfo['InsuredFee'] ?? '0',//保价费，商品保险费用，无则填“0”
                'currency'   => "142",
                'packNo'     => 1,
                'goodsInfo'  => $goodsName,
                'note'       => "",
            ],
        ];
    
        $postData = [
            'orderNo'            => $logisticsGeneralInfo['TradeId'],//订单号（客户系统自己生成，唯一）
            'orderSource'        => $this->config['SenderCompany'],//申通需要 订单来源（订阅服务时填写的来源编码）
            'billType'           => "03",
            'orderType'          => "01",
            // 'waybillNo'          => $logisticsGeneralInfo['ExpressNo'],
            'sender'             => $senderInfo,
            'receiver'           => $receiver,
            'cargo'              => $cargo,
            'customer'           => $customer,
            'internationalAnnex' => $internationalAnnex,
            'extendFieldMap'     => $extendFieldMap,
        ];
        
        if(isset($order['express_num']) && !empty($order['express_num'])){
            //运单号（下单前已获取运单号时必传，否则不传或传NULL）
            $postData['waybillNo'] = $order['express_num'];
        }
        
        $content     = json_encode($postData,JSON_UNESCAPED_UNICODE);
        $requestData = [
            'api_name'    => 'OMS_EXPRESS_ORDER_CREATE',
            'content'     => $content,
            'from_appkey' => $this->config['SyncbillParternID'],//申通需要参数
            'from_code'   => $this->config['SyncbillPartnerKey'],//申通需要参数
            'to_appkey'   => $this->config['SyncbillCustomsCode'],//申通需要参数
            'to_code'     => $this->config['SyncbillBillMode'],//申通需要参数
        ];
        
        
        $requestData['data_digest'] = $this->getSignStrByRequestDataAndKey($content, $this->config['WaybillParternID']);
        $url                        = self::API_URL . '?' . http_build_query($requestData);
        $result = $this->execute('declare',$requestData);
        if ( $result['code'] != Normal::SUC ) {
            return $result;
        }
    
        return Normal::returnCode(Normal::SUC, "运单号申报成功", [
            'waybillNo'          => $result['data']['data']['waybillNo']??'',//运单号
            'bigWord'            => $result['data']['data']['bigWord']??'',//大字/三段码
            'packagePlace'       => $result['data']['data']['packagePlace']??'',//集包地
            'originData'         => json_encode($result['data'],JSON_UNESCAPED_UNICODE),//返回的原始数据result字符串
        ]);
    }
    
    
    /**
     * 加密字符串
     * @param array $data
     * @param string $key
     */
    public function getSignStrByRequestDataAndKey(string $content, string $key) 
    {
        $str = $content . $key;
        return base64_encode(md5($str, true));
    }
    
    /**
     * 推送接口
     * @param string $method
     * @param array $body
     */
    public function execute(string $method ,array $body)
    {
        $parameter = [
            [
                'tag'       => 'sto_order_'.$method,
                'url'       => self::API_URL,
                'data'      => $body,
                'method'    => 'post',
                'format'    => 'x-www-form-urlencoded',
                'header'    => [
                ],
            ],
        ];
        $resTask    = TaskWorker::instance()->addTask($parameter);
        $resTask    = current($resTask);
        if(!$resTask['response']['result']){
            return Normal::returnCode(Normal::FAIL,"提交运单失败:[{$resTask['response']['error']}]");
        }
        $response   = @json_decode($resTask['response']['result'],true);
        if( isset($response['success']) &&  ($response['success'] === true || $response['success'] === 'true') ) {
            return Normal::returnCode(Normal::SUC,"提交运单申报成功",$response);
        }
        
        $errorMsg = json_encode($response,JSON_UNESCAPED_UNICODE);
        return Normal::returnCode(Normal::FAIL,"提交运单失败:[{$errorMsg}]");
    }
}
